home *** CD-ROM | disk | FTP | other *** search
/ Total Network Tools 2002 / NextStepPublishing-TotalNetworkTools2002-Win95.iso / Archive / Web Server / Sambar Server.exe / _SETUP.1 / javaeng.jar / javax / servlet / http / HttpUtils.java < prev   
Encoding:
Java Source  |  2000-04-03  |  7.3 KB  |  235 lines

  1. /*
  2.  * HttpUtils.java -- Several http utility methods
  3.  *
  4.  * Copyright (c) 1998, 1999 by Free Software Foundation, Inc.
  5.  * Written by Paul Siegmann (pauls@euronet.nl)
  6.  *
  7.  * This program is free software; you can redistribute it and/or modify
  8.  * it under the terms of the GNU Library General Public License as published
  9.  * by the Free Software Foundation, version 2. (see COPYING.LIB)
  10.  *
  11.  * This program is distributed in the hope that it will be useful, but
  12.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program; if not, write to the Free Software Foundation
  18.  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307 USA
  19.  */
  20.  
  21. package javax.servlet.http;
  22.  
  23. import java.io.IOException;
  24. import java.util.Hashtable;
  25. import java.util.StringTokenizer;
  26.  
  27. import javax.servlet.ServletInputStream;
  28.  
  29. /**
  30.  * A set of utility methods for http server writers.
  31.  *
  32. #ifdef SERVLET_2_0
  33.  * @version Servlet API 2.0 
  34. #endif
  35. #ifdef SERVLET_2_1
  36.  * @version Servlet API 2.1
  37. #endif
  38. #ifdef SERVLET_2_2
  39.  * @version Servlet API 2.2
  40. #endif
  41.  * @since Servlet API 1.0
  42.  */
  43. public class HttpUtils
  44. {
  45.     /**
  46.      * Creates a HttpUtils object, cool!
  47.      *
  48.      * @since Servlet API 1.0
  49.      */
  50.     public HttpUtils() {
  51.     }
  52.  
  53.  
  54.     /**
  55.      * Turns a http QUERY_STRING that conforms to
  56.      * rfc1945("Hypertext Transfer Protocol -- HTTP/1.0") or
  57.      * rfc2068 ("Hypertext Transfer Protocol -- HTTP/1.1") into a Hashtable
  58.      * with key = key and as values arrays of String.
  59.      * Implementation note: when a key or value is missing it will be
  60.      * represented as a zero length string.
  61.      *
  62.      * @since Servlet API 1.0
  63.      *
  64.      * @param queryString The queryString to process
  65.      * @return a Hashtable with String keys, and array of String values.
  66.      * @exception IllegalArgumentException If the queryString contains
  67.      * an error it can't handle.
  68.      */
  69.     public static Hashtable parseQueryString(String queryString)
  70.                     throws IllegalArgumentException {
  71.         // Use of a StringTokenizer would be easier to build and
  72.         // maintain, but leads to the creation of many unnecessary
  73.         // substring calls.
  74.         // This is a bit more work, but should be more efficient.
  75.  
  76.         if(queryString == null) {
  77.             throw new IllegalArgumentException();
  78.         }
  79.         Hashtable result = new Hashtable();
  80.  
  81.         int parameterBegin = 0;
  82.         int parameterSeparator = queryString.indexOf('=',parameterBegin);
  83.         int parameterEnd;
  84.  
  85.         while(parameterBegin < queryString.length()) {
  86.  
  87.             parameterEnd = queryString.indexOf('&',parameterBegin);
  88.             if(parameterEnd == -1) {
  89.                 parameterEnd = queryString.length();
  90.             }
  91.             if((parameterSeparator > parameterEnd)
  92.              ||(parameterSeparator < 0)) {
  93.                 addParameter(
  94.                     result,
  95.                     urlDecode(queryString,parameterBegin,parameterEnd),
  96.                     "");
  97.                     // XXX what should be the policy in this case?
  98.             } else {
  99.                 addParameter(
  100.                     result,
  101.                     urlDecode(queryString,
  102.                         parameterBegin,
  103.                         parameterSeparator),
  104.                     urlDecode(queryString,
  105.                         parameterSeparator+1,
  106.                         parameterEnd));
  107.                 parameterSeparator = queryString.indexOf('=',parameterEnd + 1);
  108.             }
  109.             parameterBegin = parameterEnd + 1;
  110.         }
  111.         return result;
  112.     }
  113.  
  114.  
  115.     private static void addParameter(Hashtable parameterTable,
  116.                         String name,
  117.                         String value) {
  118.         #ifdef DEBUG
  119.         System.out.println("javax.servlet.http.HttpUtil.addParameter:name, value: " + name + ", " + value + "\n");
  120.         #endif
  121.         try {
  122.             String[] oldArray = ((String[])parameterTable.get(name));
  123.             String[] newArray = new String[oldArray.length + 1];
  124.             System.arraycopy(oldArray,0,newArray,0,oldArray.length);
  125.             newArray[oldArray.length] = value;
  126.             parameterTable.put(name, newArray);
  127.         } catch(NullPointerException e) {
  128.             parameterTable.put(name, new String[] {value});
  129.         }
  130.     }
  131.  
  132.  
  133.     /**
  134.      * UrlDecodes a piece of the given string.
  135.      * This implementation allows characters which are officialy not
  136.      * allowed in url encoded strings. Things like spaces and characters
  137.      * like @#$ are added as-is to the result.
  138.      *
  139.      * @param firstChar index of the char to start to decoding
  140.      * @param beyondLastChar for the index <EM>after</EM> the char where
  141.      * to stop decoding. This way the caller can call
  142.      * urlDecode(s,0,s.length())
  143.      * @return the string in its url decoded form
  144.      */
  145.     private static String urlDecode(String aString, int firstChar, int beyondLastChar) throws IllegalArgumentException {
  146.  
  147.         // The problem with this initial StringBuffer size is that
  148.         // every "%xx" piece of string will result in only 1 character.
  149.         // For Strings containing many of these this will lead to
  150.         // a 3 times too large intial size.<BR>
  151.         // This could become a problem when uploading large binary
  152.         // files using a POST request.<BR>
  153.         // Setting the initial buffersize to 1/3 the length of the
  154.         // piece of text to decode would lead to a initial buffer size
  155.         // that's too short in 99% of the cases.<BR>
  156.         // *sigh* decisions, decisions.
  157.         StringBuffer result = new StringBuffer(beyondLastChar - firstChar);
  158.         char currentChar;
  159.         for(int i = firstChar; i < beyondLastChar; i++) {
  160.             currentChar = aString.charAt(i);
  161.             if (currentChar == '+') {
  162.                 result.append(" ");
  163.             } else if (currentChar == '%') {
  164.                 try {
  165. #ifdef INTL
  166.                     result.append(new String(
  167.                         new byte [] {(byte)Integer.parseInt(aString.substring(i+1, i+3),16)}
  168.                     ));
  169. #else
  170.                     result.append((char)Integer.parseInt(aString.substring(i+1, i+3),16));
  171. #endif
  172.                 } catch(StringIndexOutOfBoundsException e) {
  173.                     throw new IllegalArgumentException();
  174.                 } catch(NumberFormatException f) {
  175.                     throw new IllegalArgumentException();
  176.                 }
  177.                 i = i + 2;
  178.             } else {
  179.                 result.append(currentChar);
  180.             }
  181.         }
  182.         return result.toString();
  183.     }
  184.  
  185.  
  186.     /**
  187.      * Reads the data provided by the client using the POST method, 
  188.      * passes these on to HttpUtils.parseQueryString for further treatment,
  189.      * and returns the resulting Hashtable.
  190.      *
  191.      * @since Servlet API 1.0
  192.      *
  193.      * @return a Hashtable with String keys, and array of String values.
  194.      * @exception IllegalArgumentException If an IO error occurs or
  195.      * the POST data contains an error it can't handle.
  196.      */
  197.     public static Hashtable parsePostData(int contentLength, ServletInputStream in) throws IllegalArgumentException {
  198.         byte[] buffer = new byte[contentLength];
  199.         try {
  200.             in.read(buffer,0,buffer.length);
  201.         } catch (IOException e) {
  202.             throw new IllegalArgumentException("Error reading POST data");
  203.         }
  204.         return parseQueryString(new String(buffer));
  205.     }
  206.  
  207.  
  208.     /**
  209.      * Determines which URL the client used when issuing his request.
  210.      *
  211.      * @since Servlet API 1.0
  212.      *
  213.      * @return a URL.
  214.      */
  215.     public static StringBuffer getRequestURL(HttpServletRequest request) {
  216.         StringBuffer result = new StringBuffer("");
  217.         result.append(request.getScheme());
  218.         result.append("://");
  219.         result.append(request.getServerName());
  220.         int serverPort = request.getServerPort();
  221.         if(serverPort != 80) {
  222.             result.append(":");
  223.             result.append(serverPort);
  224.         }
  225.         result.append(request.getRequestURI());
  226.         /*
  227.         if(request.getQueryString() != null) {
  228.             result.append("?");
  229.             result.append(request.getQueryString());
  230.         }
  231.         */
  232.         return result;
  233.     }
  234. }
  235.